export class GamePlay {
  ctx = null;
  ballRadius = 10;
  x = this.ballRadius;
  y = this.ballRadius;

  offsetX = 2;
  offsetY = 2;

  paddleX = 0;
  paddleHeight = 10;
  paddleWidth = 75;

  rightPressed = false;
  leftPressed = false;

  paddleSpeed = 2;
  speedBall = 10;

  drawTimer = null;

  brickRowCount = 3;
  brickColumnCount = 3;
  brickWidth = Brick.prototype.brickWidth;
  brickHeight = Brick.prototype.brickHeight;
  brickPadding = 10;
  brickOffsetTop = 30;
  brickOffsetLeft = 30;

  score = 0;

  bricks = [];

  get canvas() {
    return this.ctx?.canvas;
  }

  constructor(canvasDom) {
    this.ctx = canvasDom.getContext("2d");
    this.init();
  }

  init() {
    this.initParam();
  }

  initParam() {
    this.paddleX = (this.canvas.width - this.paddleWidth) / 2;
    this.x = this.ballRadius;
    this.y = this.ballRadius;
    this.rightPressed = false;
    this.leftPressed = false;

    for (let c = 0; c < this.brickColumnCount; c++) {
      this.bricks[c] = [];
      for (let r = 0; r < this.brickRowCount; r++) {
        this.bricks[c][r] = new Brick();
      }
    }
  }

  play() {
    this.registerEvent();
    this.drawTimer = setInterval(() => {
      this.draw();
    }, this.speedBall);
  }

  draw() {
    this.clearCanvas();
    this.drawBricks();
    this.drawBall();
    this.drawPaddle();
    this.collisionDetection();
    this.updateBallPosition();
    this.updatePaddlePosition();
    this.drawScore();
  }

  drawScore() {
    const ctx = this.ctx;
    ctx.font = "";
  }

  collisionDetection() {
    this.bricks.forEach((brickC, indexC) => {
      brickC.forEach((brickR, indexR) => {
        if (brickR.status === 1) {
          if (brickR.collisionDetection(this.x, this.y)) {
            this.offsetY = -this.offsetY;
            brickR.status = 0;
          }
        }
      })
    })
  }

  drawBricks() {
    const ctx = this.ctx;
    this.bricks.forEach((brickC, indexC) => {
      brickC.forEach((brickR, indexR) => {
        brickR.x = indexC * (this.brickWidth + this.brickPadding) + this.brickOffsetLeft;
        brickR.y = indexR * (this.brickHeight + this.brickPadding) + this.brickOffsetTop;
        if (brickR.status !== 1) {
          return;
        }

        ctx.beginPath();
        ctx.rect(brickR.x, brickR.y, this.brickWidth, this.brickHeight);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
      })
    })
  }

  updateBallPosition() {
    if (this.y - this.ballRadius < 0) {
      this.offsetY = -this.offsetY;
    } else if (this.y + this.ballRadius > this.canvas.height) {
      if (this.x > this.paddleX && this.x < this.paddleX + this.paddleWidth) {
        this.offsetY = -this.offsetY;
      } else {
        alert("GAME OVER");
        this.stop();
        window.location.reload();
        return;
      }
    }

    if (this.x - this.ballRadius < 0 || this.x + this.ballRadius > this.canvas.width) {
      this.offsetX = -this.offsetX;
    }

    this.x += this.offsetX;
    this.y += this.offsetY;
  }

  updatePaddlePosition() {
    if (this.leftPressed && this.paddleX > 0) {
      this.paddleX -= this.paddleSpeed;
    } else if (this.rightPressed && this.paddleX < this.canvas.width - this.paddleWidth) {
      this.paddleX += this.paddleSpeed;
    }
  }

  drawBall() {
    const ctx = this.ctx;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
  }

  drawPaddle() {
    const ctx = this.ctx;
    ctx.beginPath();
    ctx.rect(this.paddleX, this.canvas.height - this.paddleHeight, this.paddleWidth, this.paddleHeight);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
  }

  clearCanvas() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }

  registerEvent() {
    this.keyDownHandler = (e) => {
      if (e.code === "ArrowLeft") {
        this.leftPressed = true;
      } else if (e.code === "ArrowRight") {
        this.rightPressed = true;
      }
    }

    this.keyUpHandler = (e) => {
      if (e.code === "ArrowLeft") {
        this.leftPressed = false;
      } else if (e.code === "ArrowRight") {
        this.rightPressed = false;
      }
    }

    document.addEventListener("keydown", this.keyDownHandler, false);
    document.addEventListener("keyup", this.keyUpHandler, false);
  }

  restart() {
    this.stop();
    this.init();
    this.play();
  }

  stop() {
    clearInterval(this.drawTimer);
    this.drawTimer = null;
    document.removeEventListener("keydown", this.keyDownHandler, false);
    document.removeEventListener("keyup", this.keyUpHandler, false);
  }

  pause() {
    this.pauseFlag = true;
  }

  start() {

  }
}


class Brick {
  x = 0;
  y = 0
  status = 1;

  collisionDetection(x, y) {
    if (
      (x > this.x && x < this.x + this.brickWidth)
      && (y > this.y && y < this.y + this.brickHeight)
    ) {
      return true;
    }

    return false;
  }
}

Brick.prototype.brickWidth = 75;
Brick.prototype.brickHeight = 20;
